#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
应用状态解析器
解析窗口信息并格式化为前端需要的格式
作者：adnaan
"""

import re
from typing import Dict, Optional, Tuple


class AppStatusParser:
    """应用状态解析器"""
    
    # 应用分类映射
    APP_CATEGORIES = {
        'editors': {
            'cursor': 'Cursor',
            'code': 'VS Code',
            'pycharm64': 'PyCharm',
            'idea64': 'IntelliJ IDEA',
            'webstorm64': 'WebStorm',
            'sublime_text': 'Sublime Text',
            'notepad++': 'Notepad++',
            'vim': 'Vim',
            'emacs': 'Emacs',
        },
        'browsers': {
            'chrome': 'Chrome',
            'firefox': 'Firefox',
            'edge': 'Edge',
            'opera': 'Opera',
            'brave': 'Brave',
        },
        'music': {
            'spotify': 'Spotify',
            'netease': '网易云音乐',
            'qqmusic': 'QQ音乐',
            'foobar2000': 'Foobar2000',
            'winamp': 'Winamp',
            'kugou': '酷狗音乐',
            'kuwo': '酷我音乐',
            'aimp': 'AIMP',
        },
        'video': {
            'potplayer': 'PotPlayer',
            'vlc': 'VLC',
            'mpc-hc': 'MPC-HC',
        },
        'office': {
            'winword': 'Word',
            'excel': 'Excel',
            'powerpnt': 'PowerPoint',
        },
        'communication': {
            'wechat': '微信',
            'weixin': '微信',
            'qq': 'QQ',
            'discord': 'Discord',
            'telegram': 'Telegram',
        }
    }
    
    # 应用图标映射（小写）
    APP_ICONS = {
        'cursor': 'vscode',
        'code': 'vscode',
        'pycharm64': 'vscode',
        'idea64': 'vscode',
        'webstorm64': 'vscode',
        'sublime_text': 'sublime',
        'notepad++': 'notepad',
        'chrome': 'chrome',
        'firefox': 'firefox',
        'edge': 'edge',
        'spotify': 'spotify',
        'netease': 'netease',
        'qqmusic': 'qqmusic',
        'potplayer': 'potplayer',
        'vlc': 'vlc',
        'discord': 'discord',
        'wechat': 'default',
        'weixin': 'default',
    }
    
    def __init__(self):
        """初始化解析器"""
        pass
    
    def get_app_category(self, raw_app_name: str) -> Tuple[str, str]:
        """
        获取应用分类和友好名称
        
        Args:
            raw_app_name: 原始应用名称（例如：cursor.exe）
            
        Returns:
            (分类, 友好名称)
        """
        app_key = raw_app_name.lower().replace('.exe', '')
        
        for category, apps in self.APP_CATEGORIES.items():
            for key, friendly_name in apps.items():
                if key in app_key:
                    return category, friendly_name
        
        # 未识别的应用
        clean_name = raw_app_name.replace('.exe', '').capitalize()
        return 'default', clean_name
    
    def get_app_icon(self, raw_app_name: str) -> str:
        """
        获取应用图标名称
        
        Args:
            raw_app_name: 原始应用名称
            
        Returns:
            图标名称
        """
        app_key = raw_app_name.lower().replace('.exe', '')
        
        for key, icon in self.APP_ICONS.items():
            if key in app_key:
                return icon
        
        return 'default'
    
    def parse_editor_info(self, app_name: str, window_title: str) -> Dict[str, str]:
        """
        解析编辑器信息
        
        例如：
        Cursor - app-status.tsx - Blog - Cursor [管理员]
        -> 文件名: app-status.tsx, 项目名: Blog
        
        Args:
            app_name: 应用名称
            window_title: 窗口标题
            
        Returns:
            解析后的信息
        """
        # 常见的编辑器标题格式：
        # Cursor: filename - project - Cursor [管理员]
        # VS Code: filename - project - Visual Studio Code
        # PyCharm: filename - project - PyCharm
        
        # 尝试提取文件名和项目名
        file_name = None
        project_name = None
        
        # 移除应用名称、管理员标记和其他后缀
        title = window_title
        # 移除 [管理员]、[Administrator] 等标记
        title = re.sub(r'\s*\[(?:管理员|Administrator|Admin)\]', '', title)
        # 移除应用名称后缀
        title = re.sub(r'\s*-\s*Cursor(?:\s|$)', '', title)
        title = re.sub(r'\s*-\s*Visual Studio Code', '', title)
        title = re.sub(r'\s*-\s*PyCharm.*?$', '', title)
        title = re.sub(r'\s*-\s*IntelliJ IDEA.*?$', '', title)
        title = re.sub(r'\s*-\s*WebStorm.*?$', '', title)
        # 移除应用名称（通用，移除最后一个 - 后面的部分，如果看起来像应用名）
        title = re.sub(r'\s*-\s*' + re.escape(app_name) + r'(?:\s|$)', '', title)
        
        # 更智能的解析：优先提取看起来像文件名的部分
        # 文件名通常包含 . 和文件扩展名
        file_pattern = r'([a-zA-Z0-9_\-\.]+\.[a-zA-Z0-9]+)'
        file_match = re.search(file_pattern, title)
        
        if file_match:
            file_name = file_match.group(1)
            # 提取项目名：在文件名之前的部分
            before_file = title[:file_match.start()].strip()
            # 移除末尾的 - 
            before_file = re.sub(r'\s*-\s*$', '', before_file)
            if before_file:
                # 分割并取第一个 - 后面的部分作为项目名（通常是项目名）
                parts = [p.strip() for p in before_file.split('-') if p.strip()]
                # 优先取第二个部分（通常是项目名），如果没有就取最后一个
                if len(parts) >= 2:
                    project_name = parts[1]  # 第二个部分通常是项目名
                elif len(parts) == 1:
                    project_name = parts[0]
        else:
            # 如果没有找到文件名，使用分割方法
            parts = [p.strip() for p in title.split('-') if p.strip()]
            
            if len(parts) >= 2:
                file_name = parts[0]  # 第一部分通常是文件名
                project_name = parts[1]  # 第二部分通常是项目名
            elif len(parts) == 1:
                file_name = parts[0]
        
        # 如果没有提取到文件名，使用窗口标题的前50个字符
        if not file_name:
            file_name = window_title[:50]
        
        return {
            'file_name': file_name,
            'project_name': project_name or '',
        }
    
    def parse_browser_info(self, app_name: str, window_title: str) -> Dict[str, str]:
        """
        解析浏览器信息
        
        例如：
        星河代码匣 📦｜光阴副本里的技术拾荒集 - Google Chrome
        -> 页面标题: 星河代码匣 📦｜光阴副本里的技术拾荒集
        
        Args:
            app_name: 应用名称
            window_title: 窗口标题
            
        Returns:
            解析后的信息
        """
        # 移除浏览器名称
        title = window_title
        title = re.sub(r'\s*-\s*Google Chrome$', '', title)
        title = re.sub(r'\s*-\s*Mozilla Firefox$', '', title)
        title = re.sub(r'\s*-\s*Microsoft​ Edge$', '', title)
        title = re.sub(r'\s*-\s*Opera$', '', title)
        
        # 提取页面标题（限制长度）
        page_title = title.strip()
        if len(page_title) > 50:
            page_title = page_title[:47] + '...'
        
        return {
            'page_title': page_title,
        }
    
    def parse_music_info(self, app_name: str, window_title: str) -> Dict[str, str]:
        """
        解析音乐播放器信息
        
        例如：
        网易云音乐 - 歌名 - 歌手
        -> 歌名: 歌名, 歌手: 歌手
        
        Args:
            app_name: 应用名称
            window_title: 窗口标题
            
        Returns:
            解析后的信息
        """
        title = window_title.strip()
        
        # 移除播放器名称
        title = re.sub(r'^(网易云音乐|QQ音乐|酷狗音乐|酷我音乐|Spotify|Foobar2000|Winamp)\s*-\s*', '', title)
        
        # 尝试提取歌名和歌手
        parts = [p.strip() for p in title.split('-') if p.strip()]
        
        song_name = None
        artist = None
        
        if len(parts) >= 2:
            song_name = parts[0]
            artist = parts[1]
        elif len(parts) == 1:
            song_name = parts[0]
        
        if not song_name:
            song_name = title[:50]
        
        return {
            'song_name': song_name,
            'artist': artist or '',
        }
    
    def parse_app_status(self, raw_app_name: str, window_title: str) -> Dict[str, any]:
        """
        解析应用状态
        
        Args:
            raw_app_name: 原始应用名称（例如：cursor.exe）
            window_title: 窗口标题
            
        Returns:
            格式化后的状态信息，包含：
            - appName: 应用友好名称
            - appIcon: 应用图标
            - appType: 应用类型（app/music）
            - action: 动作状态（编辑/浏览/播放/使用中）
            - detail: 详细信息
            - displayInfo: 完整显示信息
        """
        # 获取应用分类和友好名称
        category, friendly_name = self.get_app_category(raw_app_name)
        icon = self.get_app_icon(raw_app_name)
        
        # 根据分类解析详细信息
        action = '使用中'
        detail = window_title
        app_type = 'app'
        
        if category == 'editors':
            # 编辑器：提取文件名和项目名
            info = self.parse_editor_info(friendly_name, window_title)
            action = '编辑'
            
            if info['file_name']:
                detail = info['file_name']
                if info['project_name']:
                    detail += f" ({info['project_name']})"
        
        elif category == 'browsers':
            # 浏览器：提取页面标题
            info = self.parse_browser_info(friendly_name, window_title)
            action = '浏览'
            detail = info['page_title']
        
        elif category == 'music':
            # 音乐播放器：提取歌名和歌手
            info = self.parse_music_info(friendly_name, window_title)
            action = '播放'
            app_type = 'music'
            
            if info['song_name']:
                detail = info['song_name']
                if info['artist']:
                    detail += f" - {info['artist']}"
        
        elif category == 'video':
            # 视频播放器
            action = '播放'
            # 尝试从标题提取视频名称
            video_title = re.sub(r'\s*-\s*(PotPlayer|VLC|MPC-HC).*?$', '', window_title).strip()
            if video_title:
                detail = video_title
        
        elif category == 'office':
            # 办公软件
            action = '编辑'
            # 提取文档名称
            doc_name = re.sub(r'\s*-\s*(Word|Excel|PowerPoint).*?$', '', window_title).strip()
            if doc_name:
                detail = doc_name
        
        elif category == 'communication':
            # 通讯软件
            action = '使用中'
            # 尝试提取聊天对象
            chat_target = re.sub(r'\s*-\s*(微信|QQ|Discord|Telegram).*?$', '', window_title).strip()
            if chat_target:
                detail = chat_target
        
        elif category == 'default':
            # 未配置的应用，尝试智能识别应用类型
            action = '使用中'
            
            # 根据窗口标题特征智能识别应用类型
            title_lower = window_title.lower()
            
            # 检测是否像编辑器（包含文件路径或代码相关关键词）
            if any(keyword in title_lower for keyword in ['.py', '.js', '.ts', '.java', '.cpp', '.c', '.go', '.rs', 
                                                           'file://', 'project', 'workspace', 'folder', 'src/', 'lib/']):
                action = '编辑'
            # 检测是否像浏览器（包含网址或网页相关关键词）
            elif any(keyword in title_lower for keyword in ['http://', 'https://', 'www.', '.com', '.org', '.net', 
                                                             'google', 'github', 'stackoverflow', 'youtube']):
                action = '浏览'
            # 检测是否像音乐播放器（包含音乐相关关键词）
            elif any(keyword in title_lower for keyword in ['music', '音乐', 'song', '歌曲', 'artist', '歌手', 
                                                             'album', '专辑', 'spotify', 'netease', 'qq music']):
                action = '播放'
            
            # 尝试从窗口标题提取有用信息
            if window_title and window_title != friendly_name:
                detail = window_title
        
        # 限制detail长度
        if len(detail) > 80:
            detail = detail[:77] + '...'
        
        # 构建完整的displayInfo（原始格式，用于兼容）
        display_info = f"{friendly_name} - {window_title}"
        if len(display_info) > 100:
            display_info = display_info[:97] + '...'
        
        # 获取应用key用于配置匹配
        app_key = raw_app_name.lower().replace('.exe', '')
        for cat_apps in self.APP_CATEGORIES.values():
            for key, name in cat_apps.items():
                if key in app_key:
                    app_key = key
                    break
        
        # 构建返回数据，包含所有解析字段
        result = {
            'appName': friendly_name,
            'appIcon': icon,
            'appType': app_type,
            'appKey': app_key,  # 应用分类key
            'action': action,
            'detail': detail,
            'displayInfo': display_info,
            'raw_app_name': raw_app_name,
            'window_title': window_title,
            # 额外字段用于模板
            'file_name': '',
            'project_name': '',
            'page_title': '',
            'song_name': '',
            'artist': '',
        }
        
        # 根据分类添加额外字段
        if category == 'editors':
            info = self.parse_editor_info(friendly_name, window_title)
            result['file_name'] = info['file_name']
            result['project_name'] = info['project_name']
        elif category == 'browsers':
            info = self.parse_browser_info(friendly_name, window_title)
            result['page_title'] = info['page_title']
        elif category == 'music':
            info = self.parse_music_info(friendly_name, window_title)
            result['song_name'] = info['song_name']
            result['artist'] = info['artist']
        elif category == 'default':
            # 对于未配置的应用，尝试通用解析
            # 尝试作为编辑器解析（提取文件名）
            info = self.parse_editor_info(friendly_name, window_title)
            if info['file_name']:
                result['file_name'] = info['file_name']
                result['project_name'] = info['project_name']
            
            # 尝试作为浏览器解析（提取页面标题）
            info = self.parse_browser_info(friendly_name, window_title)
            if info['page_title']:
                result['page_title'] = info['page_title']
        
        return result


# 测试代码
if __name__ == '__main__':
    parser = AppStatusParser()
    
    # 测试用例
    test_cases = [
        ('cursor.exe', 'app-status.tsx - Blog - Cursor [管理员]'),
        ('chrome.exe', '星河代码匣 📦｜光阴副本里的技术拾荒集 - Google Chrome'),
        ('netease.exe', '网易云音乐 - 告白气球 - 周杰伦'),
        ('code.exe', 'main.py - light-capture - Visual Studio Code'),
        ('potplayer.exe', '电影名称 - PotPlayer'),
    ]
    
    print("=" * 80)
    print("应用状态解析器测试")
    print("=" * 80)
    
    for raw_app, title in test_cases:
        result = parser.parse_app_status(raw_app, title)
        print(f"\n原始输入:")
        print(f"  应用: {raw_app}")
        print(f"  标题: {title}")
        print(f"\n解析结果:")
        print(f"  应用名: {result['appName']}")
        print(f"  图标: {result['appIcon']}")
        print(f"  类型: {result['appType']}")
        print(f"  动作: {result['action']}")
        print(f"  详情: {result['detail']}")
        print(f"  完整信息: {result['displayInfo']}")
        print("-" * 80)

